package com.fub.view;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

import com.fub.guidance.BuildingDAO;
import com.fub.guidance.Point;
import com.fub.guidance.Wall;
import com.fub.util.PreferenceDAO;

public class BuildingPreView extends View {

	private static final int WALL_HEIGHT = 8;
	private Paint paintWall;
	private Paint paintWall3DFill;
	private Paint paintTextBold;
	private Paint paintText;
	private BuildingDAO wallDBService;
	private PreferenceDAO preferenceDAO;
	private Canvas canvas;
	private int parentWidth;
	private int parentHeight;
	private float width;
	private float height;
	private List<Wall> walls;
	private float factor;

	public BuildingPreView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.preferenceDAO = new PreferenceDAO(context);
		this.wallDBService = new BuildingDAO(context);
		this.walls = this.wallDBService.getWalls(this.preferenceDAO
				.getBuildingId());
		initPaints();
	}

	private void initPaints() {
		this.paintWall = new Paint(Paint.ANTI_ALIAS_FLAG);
		this.paintWall.setStyle(Paint.Style.STROKE);
		this.paintWall.setColor(Color.argb(100, 255, 255, 255));
		this.paintWall.setStrokeWidth(1);
		this.paintWall.setAntiAlias(true);

		this.paintWall3DFill = new Paint(Paint.ANTI_ALIAS_FLAG);
		this.paintWall3DFill.setStyle(Paint.Style.FILL);
		this.paintWall3DFill.setColor(Color.argb(50, 255, 255, 255));
		this.paintWall3DFill.setAntiAlias(true);

		this.paintTextBold = new Paint();
		this.paintTextBold.setAntiAlias(true);
		this.paintTextBold.setTypeface(Typeface.DEFAULT_BOLD);
		this.paintTextBold.setStyle(Paint.Style.FILL);
		this.paintTextBold.setTextSize(12);
		this.paintTextBold.setColor(Color.WHITE);

		this.paintText = new Paint();
		this.paintText.setAntiAlias(true);
		this.paintText.setStyle(Paint.Style.FILL);
		this.paintText.setTextSize(12);
		this.paintText.setColor(Color.WHITE);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		this.canvas = canvas;
		this.walls = this.wallDBService.getWalls(this.preferenceDAO
				.getBuildingId());
		this.factor = getFactor(this.walls, this.parentWidth, this.parentHeight);
		Path p = new Path();
		for (Wall wall : this.walls) {
			Point from = new Point((int) (wall.getX1() / this.factor),
					(int) (wall.getY1() / this.factor / 2 + WALL_HEIGHT), 0);
			Point to = new Point((int) (wall.getX2() / this.factor),
					(int) (wall.getY2() / this.factor / 2 + WALL_HEIGHT), 0);
			p.moveTo(wall.getX1() / this.factor, wall.getY1()
					/ (this.factor * 2));
			p.lineTo(wall.getX2() / this.factor, wall.getY2()
					/ (this.factor * 2));
			p.moveTo(wall.getX1() / this.factor, wall.getY1()
					/ (this.factor * 2) + WALL_HEIGHT);
			p.lineTo(wall.getX2() / this.factor, wall.getY2()
					/ (this.factor * 2) + WALL_HEIGHT);

			drawWallFill(from, to, WALL_HEIGHT);

		}
		canvas.drawPath(p, this.paintWall);
		canvas.drawText("Aktiviert", 0, this.paintTextBold.getTextSize(),
				this.paintTextBold);
		canvas.drawText(this.preferenceDAO.getBuildingId(), 0,
				this.paintTextBold.getTextSize() * 2, this.paintText);

		super.onDraw(canvas);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		this.parentWidth = MeasureSpec.getSize(widthMeasureSpec);
		this.parentHeight = MeasureSpec.getSize(heightMeasureSpec);
		this.factor = getFactor(this.walls, this.parentWidth, this.parentHeight);
		setMeasuredDimension((int) this.width, (int) this.height / 2 + 2
				* WALL_HEIGHT);
	}

	private void drawWallFill(Point fromOnDisplay, Point toOnDisplay,
			int wallHeight) {
		Path p = new Path();
		p.moveTo(fromOnDisplay.getX(), fromOnDisplay.getY());
		p.lineTo(toOnDisplay.getX(), toOnDisplay.getY());
		fromOnDisplay.move(0, -wallHeight);
		toOnDisplay.move(0, -wallHeight);
		p.lineTo(toOnDisplay.getX(), toOnDisplay.getY());
		p.lineTo(fromOnDisplay.getX(), fromOnDisplay.getY());
		fromOnDisplay.move(0, wallHeight);
		p.lineTo(fromOnDisplay.getX(), fromOnDisplay.getY());
		this.canvas.drawPath(p, this.paintWall3DFill);
	}

	private float getFactor(List<Wall> walls, int rectWidth, int rectHeight) {
		float xMin = getMinX(walls);
		float xMax = getMaxX(walls);
		float xDistance = xMax - xMin;
		float xFactor = xDistance / rectWidth;

		float yMin = getMinY(walls);
		float yMax = getMaxY(walls);
		float yDistance = yMax - yMin;
		float yFactor = yDistance / rectHeight;

		float factor;

		if (xFactor > yFactor) {
			factor = xFactor;
		} else {
			factor = yFactor;
		}
		this.width = xDistance / factor;
		this.height = yDistance / factor;
		return factor;
	}

	private float getMinX(List<Wall> walls) {
		int min = Integer.MAX_VALUE;
		for (Wall wall : walls) {
			if (wall.getX1() < min) {
				min = wall.getX1();
			}
		}
		return min;
	}

	private float getMinY(List<Wall> walls) {
		int min = Integer.MAX_VALUE;
		for (Wall wall : walls) {
			if (wall.getY1() < min) {
				min = wall.getY1();
			}
		}
		return min;
	}

	private float getMaxX(List<Wall> walls) {
		int max = 0;
		for (Wall wall : walls) {
			if (wall.getX1() > max) {
				max = wall.getX1();
			}
		}
		return max;
	}

	private float getMaxY(List<Wall> walls) {
		int max = 0;
		for (Wall wall : walls) {
			if (wall.getY1() > max) {
				max = wall.getY1();
			}
		}
		return max;
	}
}
